[id].tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { useFormState } from "react-use-form-state";
  2. import { Flex } from "rebass/styled-components";
  3. import React, { useState } from "react";
  4. import { NextPage } from "next";
  5. import { useRouter } from "next/router";
  6. import axios from "axios";
  7. import AppWrapper from "../../components/AppWrapper";
  8. import { TextInput } from "../../components/Input";
  9. import { Button } from "../../components/Button";
  10. import Text, { H2 } from "../../components/Text";
  11. import { Col } from "../../components/Layout";
  12. import Icon from "../../components/Icon";
  13. import { APIv2 } from "../../consts";
  14. interface Props {
  15. protectedLink?: string;
  16. }
  17. const ProtectedPage: NextPage<Props> = () => {
  18. const router = useRouter();
  19. const [loading, setLoading] = useState(false);
  20. const [formState, { password }] = useFormState<{ password: string }>();
  21. const [error, setError] = useState<string>();
  22. const onSubmit = async (e) => {
  23. e.preventDefault();
  24. const { password } = formState.values;
  25. if (!password) {
  26. return setError("Password must not be empty.");
  27. }
  28. setError("");
  29. setLoading(true);
  30. try {
  31. const { data } = await axios.post(
  32. `${APIv2.Links}/${router.query.id}/protected`,
  33. {
  34. password
  35. }
  36. );
  37. window.location.replace(data.target);
  38. } catch ({ response }) {
  39. setError(response.data.error);
  40. }
  41. setLoading(false);
  42. };
  43. return (
  44. <AppWrapper>
  45. {!router.query.id ? (
  46. <H2 my={4} light>
  47. 404 | Link could not be found.
  48. </H2>
  49. ) : (
  50. <Col width={500} maxWidth="97%">
  51. <H2 my={3} bold>
  52. Protected link
  53. </H2>
  54. <Text mb={4}>Enter the password to be redirected to the link.</Text>
  55. <Flex
  56. as="form"
  57. alignItems="center"
  58. onSubmit={onSubmit}
  59. style={{ position: "relative" }}
  60. >
  61. <TextInput
  62. {...password("password")}
  63. placeholder="Password"
  64. autocomplete="off"
  65. height={[44, 54]}
  66. width={[1, 1 / 2]}
  67. mr={3}
  68. autoFocus
  69. required
  70. />
  71. <Button type="submit" height={[40, 44]}>
  72. {loading && <Icon name={"spinner"} stroke="white" mr={2} />}
  73. Go
  74. </Button>
  75. </Flex>
  76. <Text fontSize={14} color="red" mt={3} normal>
  77. {error}
  78. </Text>
  79. </Col>
  80. )}
  81. </AppWrapper>
  82. );
  83. };
  84. ProtectedPage.getInitialProps = async ({ req }) => {
  85. return {
  86. protectedLink: req && (req as any).protectedLink
  87. };
  88. };
  89. export default ProtectedPage;